home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / comms / pipeln10.zip / VALVE.C < prev    next >
Text File  |  1990-06-01  |  16KB  |  553 lines

  1. /***************************************************************************
  2.  *     VALVE vers 1.10, DOS                                                *
  3.  *     Control program for TSRs PIPELINE and AQUEDUCT                      *
  4.  *     03/06/90                                                            *
  5.  *     by James W. Birdsall                                                *
  6.  *                                                                         *
  7.  *     compiles under Turbo C 2.0                                          *
  8.  *                                                                         *
  9.  *   This program contains the large-scale control functions for the TSRs  *
  10.  *   PIPELINE and AQUEDUCT, which connect COM1 and COM2 in software.       *
  11.  *   VALVE sets up the COM ports, enables and disables the TSR, and        *
  12.  *   removes it.                                                           *
  13.  *                                                                         *
  14.  ***************************************************************************/
  15.  
  16.  
  17. #include <stdio.h>
  18. #include <dos.h>
  19. #include <stdlib.h>
  20. #include <bios.h>
  21. #include <ctype.h>
  22.  
  23.  
  24.  
  25. #define INTERFACEINT   0xF1    /* interrupt # of TSR/VALVE interface */
  26.  
  27. #define INTCONTROLPORT 0x21    /* 8259A interrupt enable mask port */
  28. #define INTENABLE      0x01    /* type of interrupt to enable on UARTs */
  29. #define LINEEMASK      0x0B    /* mask: enable UART interrupts, raise lines */
  30. #define LINEDMASK      0xF7    /* mask: disable UART interrupts, leave lines */
  31.  
  32.  
  33. /* TO CHANGE FROM COM1 OR COM2, CHANGE THE */
  34. /* FOLLOWING INTERRUPT AND PORT VALUES     */
  35. #define DISABLEMASK    0x18    /* mask to enable COM port interrupts */
  36. #define ENABLEMASK     0xE7    /* mask to disable COM port interrupts */
  37.  
  38. #define COM1INT        0x0C    /* interrupt number for COM1 */
  39. #define COM2INT        0x0B    /* interrupt number for COM2 */
  40.  
  41. #define COM1IER        0x3F9   /* Interrupt Enable Register on COM1 */
  42. #define COM1MCR        0x3FC   /* Modem Control Register on COM1 */
  43.  
  44. #define COM2IER        0x2F9   /* Interrupt Enable Register on COM2 */
  45. #define COM2MCR        0x2FC   /* Modem Control Register on COM2 */
  46. /* END OF INTERRUPT AND PORT VALUES */
  47.  
  48.  
  49. #define ENA            0x1     /* internal flags */
  50. #define DISA           0x0
  51. #define CHAIN          0x1
  52. #define NOCHAIN        0x0
  53. #define USER           0x0
  54. #define INTERNAL       0x1
  55. #define CHAINOFF       0x0
  56. #define CHAINON        0x2
  57.  
  58. #define AQUEDUCT       'A'     /* TSR identifiers */
  59. #define PIPELINE       'P'
  60.  
  61. #undef inportb
  62. #undef outportb
  63.  
  64.  
  65.  
  66. char copyright[] = "Copyright (c) 1990 James W. Birdsall. All Rights Reserved";
  67. char VERSION[] = "1.10";
  68.  
  69.  
  70.  
  71. /* structure of data within TSR */
  72. typedef struct {
  73.    int errors;
  74.    void far *B;
  75.    void far *oldB;
  76.    void far *C;
  77.    void far *oldC;
  78.    unsigned int PSPseg;
  79.    void far *oldinterface;
  80.    char enabled;
  81.    char chain;
  82.    /* the following fields are found only in AQUEDUCT */
  83.    int one_in_head, one_in_tail, two_in_head, two_in_tail;
  84.    char busyflag;
  85.    } paramblock;
  86.  
  87. /* structure of a DOS Memory Control Block */
  88. typedef struct {
  89.    unsigned char type;
  90.    unsigned int owner;
  91.    unsigned int size;
  92.    char junk[11];
  93.    } MCB;
  94.  
  95.  
  96.  
  97. void swapvect(paramblock far *, int);
  98. paramblock far *instcheck(void);
  99. void disable_pipe(paramblock far *, int);
  100. void enable_pipe(paramblock far *, int);
  101. int remove_pipe(paramblock far *);
  102. void setup(paramblock far *, int, char *[]);
  103. void usage(void);
  104.  
  105.  
  106.  
  107. char TSRtype;          /* stores type of TSR found */
  108. char *TSRname;         /* pointer to name of TSR found */
  109.  
  110.  
  111. /**************************************************************************
  112.  *     MAIN                                                               *
  113.  *   Handles argument parsing, etc.                                       *
  114.  **************************************************************************/
  115. main(int argc, char *argv[])
  116. {
  117.    paramblock far *params;
  118.    int temp;
  119.  
  120.    /* check arguments */
  121.    if (argc < 1) {
  122.       usage();
  123.       }
  124.  
  125.    /* check for installation and get far pointer to parameter block */
  126.    params = instcheck();
  127.  
  128.    /* act according to first argument */
  129.    switch (argv[1][0]) {
  130.  
  131.       /* SETUP */
  132.       case 'S':
  133.       case 's':
  134.          setup(params, argc, argv);
  135.          printf("%s set up and enabled OK.\n", TSRname);
  136.          break;
  137.  
  138.       /* ENABLE OR ERROR COUNT */
  139.       case 'E':
  140.       case 'e':
  141.          /* ENABLE */
  142.          if ((argv[1][1] == 'N') || (argv[1][1] == 'n')) {
  143.             temp = USER | ((toupper(argv[2][0]) == 'C') ? CHAINON : CHAINOFF);
  144.             enable_pipe(params, temp);
  145.             printf("%s enabled.\n", TSRname);
  146.             }
  147.            /* ERROR COUNT */
  148.            else if (toupper(argv[1][1]) == 'R') {
  149.             printf("Error count is %d.\n", params->errors);
  150.             params->errors = 0;
  151.             }
  152.            else {
  153.             usage();
  154.             }
  155.          break;
  156.  
  157.       /* DISABLE */
  158.       case 'D':
  159.       case 'd':
  160.          disable_pipe(params, USER);
  161.          printf("%s disabled.\n", TSRname);
  162.          break;
  163.  
  164.       /* REMOVE */
  165.       case 'R':
  166.       case 'r':
  167.          if (remove_pipe(params)) {
  168.             printf("Removal of %s failed\n", TSRname);
  169.             }
  170.            else {
  171.             printf("%s removed OK.\n", TSRname);
  172.             }
  173.          break;
  174.  
  175.       /* BAD COMMAND */
  176.       default:
  177.          usage();
  178.          break;
  179.       }
  180.  
  181.    exit(0);
  182. } /* end of MAIN */
  183.  
  184.  
  185.  
  186. /**************************************************************************
  187.  *     SETUP                                                              *
  188.  *   Sets up the comm ports.                                              *
  189.  **************************************************************************/
  190. void setup(paramblock far *params, int argc, char *argv[])
  191. {
  192.    int baud;
  193.    unsigned char biosparam = 0x0;
  194.  
  195.    /* check arguments */
  196.    if (argc < 4) {
  197.       usage();
  198.       }
  199.  
  200.    /* get baud */
  201.    if ((baud = atoi(argv[2])) == 0) {
  202.       usage();
  203.       }
  204.    switch (baud) {
  205.       case 110:
  206.          break;
  207.       case 150:
  208.          biosparam |= 0x20;
  209.          break;
  210.       case 300:
  211.          biosparam |= 0x40;
  212.          break;
  213.       case 600:
  214.          biosparam |= 0x60;
  215.          break;
  216.       case 1200:
  217.          biosparam |= 0x80;
  218.          break;
  219.       case 2400:
  220.          biosparam |= 0xA0;
  221.          break;
  222.       case 4800:
  223.          biosparam |= 0xC0;
  224.          break;
  225.       case 9600:
  226.          biosparam |= 0xE0;
  227.          break;
  228.       default:
  229.          usage();
  230.          break;
  231.       }
  232.  
  233.    /* get data bits */
  234.    switch (argv[3][0]) {
  235.       case '7':
  236.          biosparam |= 0x02;
  237.          break;
  238.       case '8':
  239.          biosparam |= 0x03;
  240.          break;
  241.       default:
  242.          usage();
  243.          break;
  244.       }
  245.  
  246.    /* get parity */
  247.    switch (argv[3][1]) {
  248.       case 'N':
  249.       case 'n':
  250.          break;
  251.       case 'O':
  252.       case 'o':
  253.          biosparam |= 0x08;
  254.          break;
  255.       case 'E':
  256.       case 'e':
  257.          biosparam |= 0x18;
  258.          break;
  259.       default:
  260.          usage();
  261.          break;
  262.       }
  263.  
  264.    /* get stop bits */
  265.    switch (argv[3][2]) {
  266.       case '1':
  267.          break;
  268.       case '2':
  269.          biosparam |= 0x04;
  270.          break;
  271.       default:
  272.          usage();
  273.          break;
  274.       }
  275.  
  276.    /* all arguments verified, so start setup by turning pipeline off */
  277.    disable_pipe(params, INTERNAL);
  278.  
  279.    /* set up ports 1 and 2 */
  280.    bioscom(0, biosparam, 0);
  281.    bioscom(0, biosparam, 1);
  282.  
  283.    /* turn pipeline back on */
  284.    enable_pipe(params,
  285.              (INTERNAL | ((toupper(argv[4][0]) == 'C') ? CHAINON : CHAINOFF)));
  286.  
  287.    return;
  288. } /* end of SETUP */
  289.  
  290.  
  291.  
  292. /**************************************************************************
  293.  *     DISABLE_PIPE                                                       *
  294.  *   Disables the TSR.                                                    *
  295.  **************************************************************************/
  296. void disable_pipe(paramblock far *params, int caller)
  297. {
  298.    unsigned char tempbyte;
  299.  
  300.    /* check status */
  301.    if ((params->enabled == 0) && ((caller & INTERNAL) != INTERNAL)) {
  302.       printf("%s not enabled.\n", TSRname);
  303.       exit(0);
  304.       }
  305.    /* reset enable flag */
  306.    params->enabled = 0;
  307.  
  308.    /* disable all types of interrupts at UARTs */
  309.    outportb(COM1IER, 0x0);
  310.    outportb(COM2IER, 0x0);
  311.  
  312.    /* turn off interrupts at 8259A */
  313.    disable();
  314.    tempbyte = inportb(INTCONTROLPORT);
  315.    tempbyte |= DISABLEMASK;
  316.    outportb(INTCONTROLPORT, tempbyte);
  317.    enable();
  318.  
  319.    /* reset vectors */
  320.    swapvect(params, DISA);
  321.  
  322.    /* turn off interrupts at UARTs */
  323.    tempbyte = inportb(COM1MCR);
  324.    tempbyte &= LINEDMASK;
  325.    outportb(COM1MCR, tempbyte);
  326.    tempbyte = inportb(COM2MCR);
  327.    tempbyte &= LINEDMASK;
  328.    outportb(COM2MCR, tempbyte);
  329.  
  330.    return;
  331. } /* end of DISABLE_PIPE */
  332.  
  333.  
  334.  
  335. /**************************************************************************
  336.  *     ENABLE_PIPE                                                        *
  337.  *   Enables the TSR.                                                     *
  338.  **************************************************************************/
  339. void enable_pipe(paramblock far *params, int caller)
  340. {
  341.    unsigned char tempbyte;
  342.  
  343.    /* check status */
  344.    if ((params->enabled != 0) && ((caller & INTERNAL) != INTERNAL)) {
  345.       printf("%s already enabled.\n", TSRname);
  346.       exit(0);
  347.       }
  348.    /* set enable flag */
  349.    params->enabled = 1;
  350.    /* clear busy flag if AQUEDUCT */
  351.    if (TSRtype == AQUEDUCT) {
  352.       params->busyflag = 0;
  353.       }
  354.    /* clear error count */
  355.    params->errors = 0;
  356.  
  357.    /* flush buffers if AQUEDUCT */
  358.    if (TSRtype == AQUEDUCT) {
  359.       params->one_in_head = 0;
  360.       params->one_in_tail = 0;
  361.       params->two_in_head = 0;
  362.       params->two_in_tail = 0;
  363.       }
  364.  
  365.    /* set chaining if necessary */
  366.    if (caller & CHAINON) {
  367.       params->chain = CHAIN;
  368.       }
  369.  
  370.    /* disable all types of interrupts at UARTs */
  371.    outportb(COM1IER, 0x0);
  372.    outportb(COM2IER, 0x0);
  373.  
  374.    /* turn on interrupts at UARTs */
  375.    tempbyte = inportb(COM1MCR);
  376.    tempbyte |= LINEEMASK;
  377.    outportb(COM1MCR, tempbyte);
  378.    tempbyte = inportb(COM2MCR);
  379.    tempbyte |= LINEEMASK;
  380.    outportb(COM2MCR, tempbyte);
  381.  
  382.    /* set vectors */
  383.    swapvect(params, ENA);
  384.  
  385.    /* turn on interrupts at 8259A */
  386.    disable();
  387.    tempbyte = inportb(INTCONTROLPORT);
  388.    tempbyte &= ENABLEMASK;
  389.    outportb(INTCONTROLPORT, tempbyte);
  390.    enable();
  391.  
  392.    /* enable received-available interrupt at UARTs */
  393.    outportb(COM1IER, INTENABLE);
  394.    outportb(COM2IER, INTENABLE);
  395.  
  396.    return;
  397. } /* end of ENABLE_PIPE */
  398.  
  399.  
  400.  
  401. /**************************************************************************
  402.  *     SWAPVECT                                                           *
  403.  *   Installs the correct vectors in the interrupt table.                 *
  404.  **************************************************************************/
  405. void swapvect(paramblock far *params, int function)
  406. {
  407.    union REGS r;
  408.    struct SREGS s;
  409.    void far *holderB, far *holderC;
  410.  
  411.    /* enable or disable? */
  412.    if (function == ENA) {
  413.       holderB = params->B;
  414.       holderC = params->C;
  415.       }
  416.      else if (function == DISA) {
  417.       holderB = params->oldB;
  418.       holderC = params->oldC;
  419.       }
  420.      else {
  421.       return;
  422.       }
  423.  
  424.    /* set COM2 interrupt */
  425.    r.h.ah = 0x25;
  426.    r.h.al = COM2INT;
  427.    s.ds = FP_SEG(holderB);
  428.    r.x.dx = FP_OFF(holderB);
  429.    intdosx(&r, &r, &s);
  430.  
  431.    /* set COM1 interrupt */
  432.    r.h.ah = 0x25;
  433.    r.h.al = COM1INT;
  434.    s.ds = FP_SEG(holderC);
  435.    r.x.dx = FP_OFF(holderC);
  436.    intdosx(&r, &r, &s);
  437.  
  438.    return;
  439. } /* end of SWAPVECT */
  440.  
  441.  
  442.  
  443. /**************************************************************************
  444.  *     REMOVE_PIPE                                                        *
  445.  *   Disables TSR and removes it from memory.                             *
  446.  **************************************************************************/
  447. int remove_pipe(paramblock far *params)
  448. {
  449.    union REGS r;
  450.    struct SREGS s;
  451.    MCB far *temp;
  452.  
  453.    /* disable the pipe */
  454.    disable_pipe(params, INTERNAL);
  455.  
  456.    /* restore the old interface vector */
  457.    r.h.ah = 0x25;
  458.    r.h.al = INTERFACEINT;
  459.    s.ds = FP_SEG(params->oldinterface);
  460.    r.x.dx = FP_OFF(params->oldinterface);
  461.    intdosx(&r, &r, &s);
  462.  
  463.    /* release the memory block occupied by the program manually */
  464.    temp = (MCB far *) MK_FP(params->PSPseg - 1, 0x0);
  465.    if (temp->type != 0x4D) {
  466.       return 1;
  467.       }
  468.    temp->owner = 0;
  469.  
  470.    return 0;
  471. } /* end of REMOVE_PIPE */
  472.  
  473.  
  474.  
  475. /**************************************************************************
  476.  *     INSTCHECK                                                          *
  477.  *   Checks for installed TSR and returns type info.                      *
  478.  **************************************************************************/
  479. paramblock far *instcheck(void)
  480. {
  481.    union REGS r;
  482.    struct SREGS s;
  483.    char far *checker;
  484.    paramblock far *result;
  485.  
  486.    /* get interrupt vector */
  487.    r.h.ah = 0x35;
  488.    r.h.al = INTERFACEINT;
  489.    intdosx(&r, &r, &s);
  490.    checker = (char far *) MK_FP(s.es, r.x.bx);
  491.  
  492.    /* check for signature */
  493.    checker -= 6;
  494.    if ((*checker != 'J') || (*(checker+1) != 'W') || (*(checker+2) != 'B')) {
  495.       printf("Neither AQUEDUCT nor PIPELINE found.\n");
  496.       exit(0);
  497.       }
  498.  
  499.    /* check for TSR type and version */
  500.    checker += 3;
  501.    TSRtype = *checker;
  502.    switch (*checker) {
  503.       case AQUEDUCT:
  504.          TSRname = "AQUEDUCT";
  505.          break;
  506.       case PIPELINE:
  507.          TSRname = "PIPELINE";
  508.          break;
  509.       default:
  510.          printf("TSR identifier error!\n");
  511.          exit(0);
  512.          }
  513.    printf("%s vers %c.%c found.\n", TSRname, *(checker+1), *(checker+2));
  514.  
  515.    /* call interrupt to get pointer to parameter block */
  516.    int86(INTERFACEINT, &r, &r);
  517.    result = (paramblock far *) MK_FP(r.x.ax, r.x.bx);
  518.  
  519.    return result;
  520. } /* end of INSTCHECK */
  521.  
  522.  
  523.  
  524. /**************************************************************************
  525.  *     USAGE                                                              *
  526.  *   Prints usage message and exits.                                      *
  527.  **************************************************************************/
  528. void usage(void)
  529. {
  530.    printf("VALVE version %s by James W. Birdsall\n", VERSION);
  531.    printf("   for use with the TSRs PIPELINE and AQUEDUCT\n");
  532.    printf("   Usage: VALVE Setup baud DPS [Chain]\n");
  533.    printf("                ENable\n");
  534.    printf("                Disable [Chain]\n");
  535.    printf("                ERrors\n");
  536.    printf("                Remove\n");
  537.    printf("   Only the capital letters in the first argument are significant\n");
  538.    printf("   SETUP sets up the communications ports. baud is the baud rate.\n");
  539.    printf("      The TSRs support rates of 110, 150, 300, 600, 1200, 2400,\n");
  540.    printf("      4800, and 9600 baud, although rates above 2400 are not\n");
  541.    printf("      recommended on slow machines. D is data bits: 7 or 8. P is\n");
  542.    printf("      parity: E (even), O (odd), N (none). S is stop bits: 1 or 2.\n");
  543.    printf("      Chain allows chaining to previous interrupt vector if serial\n");
  544.    printf("      port did not issue the interrupt.\n");
  545.    printf("      The TSR is automatically enabled after a setup.\n");
  546.    printf("   ENABLE enables PIPELINE or AQUEDUCT. Chain is as in SETUP.\n");
  547.    printf("   DISABLE disables PIPELINE or AQUEDUCT\n");
  548.    printf("   ERRORS prints out the current error count and clears it.\n");
  549.    printf("   REMOVE disables PIPELINE or AQUEDUCT and removes it from memory.\n");
  550.    printf("\n");
  551.    exit(1);
  552. } /* end of USAGE */
  553.